/*
 * Copyright (c) 2010, Thiago Campos Viana.
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in
 *       the documentation and/or other materials provided with the
 *       distribution.
 *     * Neither the name of Thiago Campos Viana nor the names of its
 *       contributors may be used to endorse or promote products derived
 *       from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package client;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.nio.ByteBuffer;
import javax.imageio.ImageIO;
import lib.IniProperties;
import lib.MapParser;

/**
 *
 * @author Thiago
 */
public class Game extends javax.swing.JFrame implements Runnable {

    private static final int FRAME_DELAY = 40; // 20ms. implies 50fps (1000/20) = 50
    long cycleTime;
    boolean canSend=true;
    short x = 0;
    short y = 0;
    int layer =0;
    Game g;
    boolean start = false;
    String server = "localhost";
    DatagramPacket packet;
    InetAddress address;
    DatagramSocket socket;
    public int twidth;
    public int theight;
    
    int id;
    ByteBuffer received;
    BufferedImage img;
    BufferedImage[] tile = new BufferedImage[10];
    int count=8;
    public byte[][][] tileMap = new byte[16][100][100];



    /** Creates new form Game */
    public Game() {

        tileMap[0]=MapParser.getMap((byte)0, (byte)0, (byte)1);
        try {
            InputStream is = new FileInputStream("data/settings/server.ini");
            IniProperties.getInstance().load(is);
            twidth=Integer.parseInt(IniProperties.getInstance().getProperty("MapSettings", "TileWidth"));
            theight=Integer.parseInt(IniProperties.getInstance().getProperty("MapSettings", "TileHeight"));
            img = ImageIO.read(getClass().getResourceAsStream("edgepic.gif"));
            System.out.println(twidth);
            BufferedImage limg=ImageIO.read(new FileInputStream("data/images/tiles/sewer_tileset.png"));
            int total = (limg.getHeight() / theight) * (limg.getWidth() / twidth);
            System.out.println(total);
            tile = new BufferedImage[total];
            System.out.println(tile.length);
            int counter=0;
            for(int k=0;k<(limg.getHeight()/theight);k++){
                for(int j=0;j<(limg.getWidth()/twidth);j++){
                    tile[counter] = limg.getSubimage(j*twidth, k*theight, twidth, theight);
                    counter++;
                    System.out.println("counter "+counter);
                }
            }
            System.out.println("countersss "+counter);
        } catch (Exception ex) {
            ex.printStackTrace();
            //Logger.getLogger(Game.class.getName()).log(Level.SEVERE, null, ex);
        }

        initComponents();
    }

    public void run() {

        try {
            socket = new DatagramSocket();
            address = InetAddress.getByName(server);
        } catch (Exception ex) {
            //Logger.getLogger(Game.class.getName()).log(Level.SEVERE, null, ex);
        }

        addKeyListener(new KeyHandler(this));

        cycleTime = System.currentTimeMillis();
        this.createBufferStrategy(2);

        BufferStrategy strategy = this.getBufferStrategy();

        while (true) {

            try {
                update();
                updateGUI(strategy);
                synchFramerate();



            } catch (Exception ex) {
            }
        }

    }

    private void synchFramerate() {
        cycleTime = cycleTime + FRAME_DELAY;
        long difference = cycleTime - System.currentTimeMillis();
        try {
            Thread.sleep(Math.max(0, difference));
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jButton1 = new javax.swing.JButton();
        jTextField1 = new javax.swing.JTextField();
        jLabel1 = new javax.swing.JLabel();
        pass = new javax.swing.JTextField();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        jButton1.setText("jButton1");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });

        jTextField1.setText("admin");
        jTextField1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jTextField1ActionPerformed(evt);
            }
        });

        jLabel1.setText("Enter your name");

        pass.setText("admin");
        pass.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                passActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(57, 57, 57)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(pass, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel1)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(18, 18, 18)
                        .addComponent(jButton1)))
                .addContainerGap(141, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(27, 27, 27)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jButton1)
                    .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(1, 1, 1)
                .addComponent(pass, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jLabel1)
                .addContainerGap(140, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
        // TODO add your handling code here:
        if (jTextField1.getText().length() == 0 || jTextField1.getText().length() > 15) {
            jLabel1.setText("Nome deve ser maior que 0 e menor que 15");
            jTextField1.setText("username");
        } else {
            try {


                // send request
                byte[] buf = new byte[256];
                buf[0] = 0;
                buf[1] = (byte) jTextField1.getText().length();
                int k=2;
                for (int i=0; i < jTextField1.getText().length(); i++) {
                    buf[k] = jTextField1.getText().getBytes()[i];
                    k++;
                }
                buf[k] = (byte) pass.getText().length();
                k++;
                for (int j=0; j < pass.getText().length(); j++) {
                    buf[k] = pass.getText().getBytes()[j];
                    k++;
                }

                packet = new DatagramPacket(buf, buf.length, address, 4445);
                socket.send(packet);
                // get response
                packet = new DatagramPacket(buf, buf.length);
                socket.receive(packet);
                ByteBuffer r=ByteBuffer.allocate(1000);
                r.put(packet.getData());
                r.rewind();
                //byte[] serverResponse=packet.getData();
                if (r.get() == 0) {
                    jLabel1.setText("Não foi autenticado");
                    jTextField1.setText("username");
                } else {
                    start = true;
                    jButton1.setVisible(false);
                    jTextField1.setVisible(false);
                    requestFocusInWindow();




                    id = r.getInt();
                }
            } catch (IOException ex) {
                //Logger.getLogger(Game.class.getName()).log(Level.SEVERE, null, ex);
            }



        }

    }//GEN-LAST:event_jButton1ActionPerformed

    private void passActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_passActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_passActionPerformed

    private void jTextField1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jTextField1ActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_jTextField1ActionPerformed

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        Game g = new Game();
        g.setVisible(true);
        Thread gameThread = new Thread(g);
        gameThread.setPriority(Thread.MIN_PRIORITY);
        gameThread.start(); // start Game processing.
    }

    public void update() throws IOException {
        count++;
        if (start && count>=8) {
            count=0;
            canSend=true;
            received = ByteBuffer.allocate(5);

            received.put((byte)1);
            received.putInt(id);

            address = InetAddress.getByName(server);
            packet = new DatagramPacket(received.array(), received.array().length, address, 4445);
            socket.send(packet);
            // get response
            received = ByteBuffer.allocate(1000);
            packet = new DatagramPacket(received.array(), received.array().length);
            socket.receive(packet);


            received.put(packet.getData());
            received.rewind();
            if(packet.getData().length >= 5){
                layer=received.get();
                x = received.getShort();
                y = received.getShort();
            }
            
        } 

    }

    private void updateGUI(BufferStrategy strategy) {
        Graphics graphics = strategy.getDrawGraphics();

        if (start) {
            for (int h = 0; h < tileMap[layer][0].length; h++) {
                for (int j = 0; j < tileMap[layer].length; j++) {
                    graphics.drawImage(tile[tileMap[layer][j][h]], h * theight, j * twidth, null);

                }
            }
            //g.setColor(Color.white);
            //g.fillRect(0, 0, this.getSize().width, this.getSize().height);

            graphics.setColor(Color.red);
            graphics.drawString(jTextField1.getText(), x*twidth, y*theight);
            graphics.drawImage(img, x*twidth, y*theight, null);
            received.position(5);

            //g.drawString("Amo Kelly", y, x);
            //System.out.println(received[9]);
            // draw players]
            int total=received.getShort();

            for (int k = 0; k < total; k ++) {
                
                int pid = received.getInt();
                byte pLayer = received.get();
                short px=received.getShort();
                short py=received.getShort();
                byte dir=received.get();
                byte voc=received.get();
                short hp=received.getShort();
                short lvl=received.getShort();
                //short mp=received.getShort();


                if (pLayer==layer && pid!=id){
                    graphics.drawString(""+pid, px*twidth, py*theight);
                    graphics.drawImage(img, px*twidth, py*theight, null);
                }
            }

            graphics.dispose();
            strategy.show();


        }


    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton jButton1;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JTextField jTextField1;
    private javax.swing.JTextField pass;
    // End of variables declaration//GEN-END:variables


}
